import numpy as np
from clothing_data_model import ClothingItem, Outfit, UserProfile, ContextInfo
from recommendation_system import OutfitRecommendationSystemDB


class RecommendationAPI:
    """
    推荐系统API接口，用于处理推荐请求和用户反馈
    """

    def __init__(self, db_config):
        """
        初始化推荐系统API

        参数:
            db_config: 数据库配置字典，包含 host, user, password, database
        """
        # 初始化推荐系统
        self.recommendation_system = OutfitRecommendationSystemDB(db_config)

    def get_outfit_recommendation(self, user_id, weather=None, temperature=None,
                                  theme=None, date=None, season=None, n_recommendations=1):
        """
        获取服装搭配推荐

        参数:
            user_id: 用户ID
            weather: 天气情况 (如晴天、雨天等)
            temperature: 温度 (可选)
            theme: 风格主题 (如休闲、正式、运动等)
            date: 日期 (可选，格式: YYYY-MM-DD)
            season: 季节 (可选，如春季、夏季、秋季、冬季)
            n_recommendations: 推荐数量

        返回:
            推荐的服装搭配ID列表和错误信息（如果有）
        """
        # 创建上下文信息
        context = ContextInfo(date=date, weather=weather, style_theme=theme)

        # 添加场景信息（如果有）
        if hasattr(context, 'scene'):
            context.scene = None  # 默认为空

        # 如果提供了温度，添加到上下文（优先级高于季节）
        if temperature is not None:
            context.temperature = float(temperature)  # 确保温度是浮点数
            print(f"使用前端提供的温度: {context.temperature}°C")

        # 如果提供了季节但没有日期，手动设置季节
        # 注意：如果同时提供了温度，温度将优先于季节
        if season and not date:
            context.date = None  # 清除日期，以便使用手动设置的季节
            # 在ContextInfo类的get_season方法中添加对手动设置季节的处理
            context.manual_season = season
            if temperature is not None:
                print(f"同时提供了温度和季节，温度({temperature}°C)将优先于季节({season})考虑")
            else:
                print(f"使用手动设置的季节: {season}")

        # 获取推荐搭配 - 这里会使用修改后的recommend_outfit方法，只推荐用户自己的衣物
        # 确保每次调用都重置随机种子，增加随机性
        import random
        random.seed()  # 使用系统时间作为种子
        np.random.seed()  # 重置numpy随机种子
        error_info = None
        recommended_outfits, error_info = self.recommendation_system.recommend_outfit(
            user_id, context, n_recommendations=n_recommendations)

        # 如果有错误信息，直接返回
        if error_info:
            return [], error_info

        # 提取每个搭配中的衣物信息
        outfit_recommendations = []
        for outfit in recommended_outfits:
            outfit_items = []
            for item in outfit.items:
                outfit_items.append({
                    'clothes_id': item.clothes_id,
                    'category': item.category,
                    'subcategory': item.subcategory,
                    'image_url': self._get_image_url(item.clothes_id)  # 获取图片URL
                })

            outfit_recommendations.append({
                'outfit_id': outfit.outfit_id,
                'clothes_ids': [item['clothes_id'] for item in outfit_items],
                'items': outfit_items
            })

        return outfit_recommendations, error_info

    # 添加获取相似搭配的方法
    def get_similar_outfits(self, outfit_id, n_recommendations=3):
        """
        获取与指定搭配相似的其他搭配

        参数:
            outfit_id: 搭配ID
            n_recommendations: 推荐数量

        返回:
            相似搭配列表
        """
        try:
            # 获取搭配中的衣物ID
            with self.recommendation_system.db_connector.connect() as connection:
                with connection.cursor() as cursor:
                    sql = "SELECT clothes_id FROM outfit_items WHERE outfit_id = %s"
                    cursor.execute(sql, (outfit_id,))
                    clothes_ids = [row['clothes_id'] for row in cursor.fetchall()]

            if not clothes_ids:
                return []

            # 创建搭配对象
            outfit = self.recommendation_system.create_outfit_from_ids(clothes_ids)
            if not outfit:
                return []

            # 获取相似搭配
            similar_outfits = self.recommendation_system.get_similar_outfits(outfit, n=n_recommendations)

            # 提取每个搭配中的衣物信息
            outfit_recommendations = []
            for similar_outfit in similar_outfits:
                outfit_items = []
                for item in similar_outfit.items:
                    outfit_items.append({
                        'clothes_id': item.clothes_id,
                        'category': item.category,
                        'subcategory': item.subcategory,
                        'image_url': self._get_image_url(item.clothes_id)
                    })

                outfit_recommendations.append({
                    'outfit_id': similar_outfit.outfit_id,
                    'clothes_ids': [item['clothes_id'] for item in outfit_items],
                    'items': outfit_items
                })

            return outfit_recommendations
        except Exception as e:
            print(f"获取相似搭配时出错: {e}")
            return []

    def provide_feedback(self, user_id, clothes_ids, rating=None, theme=None):
        """
        处理用户对搭配的反馈

        参数:
            user_id: 用户ID
            clothes_ids: 搭配中的衣物ID列表
            rating: 评分 (1-5)，可选
            theme: 风格主题 (可选)

        返回:
            成功与否
        """
        try:
            # 从衣物ID创建搭配对象
            outfit = self.recommendation_system.create_outfit_from_ids(clothes_ids, user_id)

            if not outfit:
                return False, "无法创建搭配对象"

            # 如果提供了评分，则提供反馈
            if rating is not None:
                self.recommendation_system.provide_feedback(user_id, outfit, rating, theme)
                return True, "反馈处理成功"
            else:
                # 如果没有提供评分，只保存搭配
                return True, "搭配保存成功"
        except Exception as e:
            return False, f"处理反馈时出错: {str(e)}"

    def refresh_catalog(self):
        """刷新服装目录"""
        self.recommendation_system.refresh_catalog()
        return True, "服装目录已刷新"

    def _get_image_url(self, clothes_id):
        """
        获取衣物的图片URL

        参数:
            clothes_id: 衣物ID

        返回:
            衣物的图片URL
        """
        try:
            with self.recommendation_system.db_connector.connect() as connection:
                with connection.cursor() as cursor:
                    sql = "SELECT image_url FROM clothes WHERE clothes_id = %s"
                    cursor.execute(sql, (clothes_id,))
                    result = cursor.fetchone()
                    if result and 'image_url' in result:
                        return result['image_url']
                    return None
        except Exception as e:
            print(f"获取图片URL时出错: {e}")
            return None
